from typing import List, Dict

from sqlalchemy import or_, and_
from sqlalchemy.orm import Session, joinedload
from starlette.websockets import WebSocket, WebSocketDisconnect

from app.database import engine
from app.models import Message, Conversation, Users
from app.schemas.conversations import MessageSM, Item, ConversationsSM


class ConversationsServices:
    @staticmethod
    def message_store(form: MessageSM):
        print(form.conversation_id)
        with Session(engine, expire_on_commit=False) as session:
            try:
                message = Message(**form.dict())
                session.add(message)
                session.flush()  # 将数据提交到数据库并刷新到当前会话中
                session.refresh(message)
            except Exception as e:
                print(f"Error: {e}")
                return False
            session.query(Conversation).filter_by(id=form.conversation_id).update({'last_message_id': message.id})
            session.commit()
            return message

    @staticmethod
    def get_message(user_id: int, receiver_id: int):
        with Session(engine) as session:
            conversation = session.query(Message).filter(or_(
                and_(Message.sender_id == user_id, Message.receiver_id == receiver_id),
                and_(Message.sender_id == receiver_id, Message.receiver_id == user_id)
            )).all()
            return conversation

    @staticmethod
    def get_conversations(user_id: int):
        with Session(engine) as session:
            conversation = session.query(Conversation).options(joinedload(Conversation.participant),
                                                               joinedload(Conversation.last_message)).filter_by(
                creator_id=user_id).all()
            # items = [Item(**post.__dict__) for post in conversation]
        return conversation



    # 判断 存在对话表 不存在时创建数据
    @staticmethod
    def is_conversation(receiver_id, sender_id):
        with Session(engine) as session:
            conversation = session.query(Conversation).filter_by(creator_id=sender_id,
                                                                 participant_id=receiver_id).first()
            ## 对话是否存在
            if conversation is None:
                conSM = ConversationsSM(creator_id=sender_id, participant_id=receiver_id)
                conversation = Conversation(**conSM.dict())
                session.add(conversation)
                session.commit()
                session.refresh(conversation)
            return conversation


class ConnectionManager:
    def __init__(self):
        self.active_connections: List[WebSocket] = []

    async def connect(self, websocket: WebSocket, page):
        await websocket.accept()
        self.active_connections.append(websocket)
        if page == 'chat':
            await get_messages(user_id, receiver_id)
        elif page == 'conversation':
            await get_messages(user_id, receiver_id)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def broadcast(self, message: Dict):
        for connection in self.active_connections:
            try:
                await connection.send_json(message)
            except WebSocketDisconnect:
                self.disconnect(connection)
